<!--
 * @Author: luojiajun
 * @Email: company.kachun@gmail.com
 * @Date: 2021-06-29 14:43:42
 * @FilePath: /src/views/database/components/DatabaseDirectoryTree.vue
 * @LastEditTime: 2021-07-17 14:01:16
 * @LastEditors: luojiajun
-->
<template>
    <div class="database-dir-tree">
        <el-row>
            <el-col :span="24">
                <!-- 树形结构 -->
                <div class="database-dir-tree-table">
                    <div class="database-dir-tree-table__header flex">
                        <div class="database-dir-tree-table__header--th">
                            <span>数据目录</span>
                            <div class="database-dir-tree-table__header--switch">
                                <el-switch
                                v-model="treeExpand"
                                active-text="展开"
                                inactive-text="收起"
                                :disabled="!inputValue.length"
                                @change="handlTreeExpand"
                                >
                            </el-switch>
                            </div>
                        </div>
                        <div class="database-dir-tree-table__header--th">表字段限制</div>
                        <div class="database-dir-tree-table__header--th">启用</div>
                        <div class="database-dir-tree-table__header--th">停用</div>
                    </div>
                    <el-tree 
                        ref="tree" 
                        :data="inputValue" 
                        :default-expand-all="true" 
                        node-key="uniqueid" 
                        :filter-node-method="filterNode" 
                        class="edit-tree" 
                        :empty-text="emptyText" 
                        v-loading="loading || treeLoading" 
                        expand-on-click-node
                        >
                        <span class="custom-tree-node database-dir-tree-table__main flex" slot-scope="{ node, data }">
                            <div class="database-dir-tree-table__main--td">{{ data.dirName }}</div>
                            <div class="database-dir-tree-table__main--td" >
                                <!-- TODO 停用字段 -->
                                <span v-if="data.isTable" @click="onClickTable(data)">{{ data.disableCount }}字段停用</span>
                            </div>
                            <div class="database-dir-tree-table__main--td">
                                <el-radio-group v-model="data.status" v-if="data.isTable" @change="(value)=>{ filterSelect(data,value,node) }">
                                    <el-radio class="item-radio" :label="1">{{''}}</el-radio>
                                    <el-radio class="item-radio" :label="2">{{''}}</el-radio>
                                </el-radio-group>
                                <el-radio-group v-model="data.status" v-else-if="data.children && data.children.length > 0" @change="(value)=>{ filterSelect(data,value,node) }">
                                    <el-radio class="item-radio" :label="1">全选{{''}}</el-radio>
                                    <el-radio class="item-radio" :label="2">全选{{''}}</el-radio>
                                </el-radio-group>
                                <template v-else>
                                    <div class="el-radio-group">
                                        <span class="item-radio placeholder" v-for="i in 2" :key="i">{{i}}</span>
                                    </div>
                                </template>
                            </div>
                        </span>
                    </el-tree>
                </div>
            </el-col>
        </el-row>
        <database-directory-tree-modal v-model="dialogVisible" :table-id.sync="tableId" @close="onCloseDialog"></database-directory-tree-modal>
    </div>
</template>

<script>
import { flatten } from "@/utils/ruoyi";
import databaseDirectoryTreeModal from "@/views/database/components/DatabaseDirectoryTreeModal";
import { editDataTreeStatus } from "@/api/dataManagement/system/info.js";

export default {
    name: 'DatabaseDirectoryTree',
    components: {
        databaseDirectoryTreeModal
    },
    model: {
        prop: 'value',
        event: 'change'
    },
    props: {
        value: {
            type: Array,
            default: () => {
                return []
            }
        },
        loading: {
            type: Boolean,
            default: false
        },
        isEdit: {
            type: Boolean,
            default: false
        },
        ruleForm: {
            type: Object,
            default: () => {
                return {
                    name: '',
                    type: '',
                }
            }
        },
        rootNode: {
            type: Object,
            default: () => {
                return {}
            }
        }
    },
    data() {
        return {
            treeLoading: false,
            treeExpand: true,
            // ruleForm: {
            //     name: '',
            //     type: ''
            // },
            readonly: true,
            dialogVisible: false,
            tableId: 0
        }
    },
    watch: {
        inputValue(value) {
            if (value) {
                this.$nextTick(() => {
                    // this.$refs.tree.filter({ selectAll: true })
                })
            }
        },
        isEdit: {
            handler: function (value) {
                this.readonly = value
            },
            immediate: true
        }
    },
    computed: {
        inputValue: {
            get() {
                return this.value;
            },
            set(newValue) {
                this.$emit("change", newValue);
            },
        },
        computedLoading: {
           get() {
                return this.loading;
            },
            set(newValue) {
                this.$emit("loading", newValue);
            }, 
        },
        emptyText() {
            return this.computedLoading ? '加载中' : '暂无数据'
        }
    },
    methods: {
        handleQuery() {
            this.$refs.tree.filter(this.ruleForm)
        },
        handleQueryReset() {
            this.$refs.tree.filter('')
        },
        handlTreeExpand() {
            if (!this.$refs.tree) return

            this.treeLoading = true
            // TODO 线程阻塞，待处理
            let treeData = flatten(this.inputValue);
            for (let i = 0; i < treeData.length; i++) {
                if (treeData[i].children.length) {
                    this.$refs.tree.store.nodesMap[treeData[i].uniqueid].expanded = this.treeExpand;
                }
            }

            this.treeLoading = false
        },
        filterNode(value, data, node) {
            if (value.selectAll) {
                this.changeParent(data.status, node)
                return true
            }
            else if (!value.tableName && !value.type || value == '') {
                return true
            } else {
                return this.checkBelongToChooseNode(value, data, node);
            }
        },
        // 判断传入的节点是不是选中节点的子节点
        checkBelongToChooseNode(value, data, node) {
            let label = "dirName"
            if (value.tableName && value.type && data[label].indexOf(value.tableName) !== -1 && data.status != null && data.status.toString().indexOf(value.type) !== -1) {
                return true;
            } else if (value.tableName && data[label].indexOf(value.tableName) !== -1 && !value.type) {
                return true
            } else if (value.type && data.status != null && data.status.toString().indexOf(value.type) !== -1 && !value.tableName) {
                return true
            }
            const level = node.level;
            // 如果传入的节点本身就是一级节点就不用校验了
            if (level === 1) {
                return false;
            }
            // 先取当前节点的父节点
            let parentData = node.parent;
            // 遍历当前节点的父节点
            let index = 0;
            while (index < level - 1) {
                // 如果匹配到直接返回
                if (value.tableName && parentData.data[label].indexOf(value.tableName) !== -1 && value.type && parentData.data.status != null && parentData.data.status.toString().indexOf(value.type) !== -1) {
                    // if (parentData.data[label].indexOf(value) != -1) {
                    return true;
                } else if (value.tableName && parentData.data[label].indexOf(value.tableName) !== -1 && !value.type) {
                    return true
                } else if (value.type && parentData.data.status != null && parentData.data.status.toString().indexOf(value.type) !== -1 && !value.tableName) {
                    return true
                }
                // 否则的话再往上一层做匹配
                parentData = parentData.parent;
                index++;
            }
            // 没匹配到返回false
            return false;
        },
        // 过滤筛选
        filterSelect(data, value, node) {
            data.status = value
            if (node && node.parent) {
                this.changeParent(value, node)

            }
            if (data.children && data.children.length > 0) {
                data.children.forEach(item => {
                    this.filterSelect(item, value)
                })
            }
            // 防止全选的时候多次触发更新
            if (node) this.saveTreeStatus()
        },
        changeParent(value, node) {
            if (node.data.isTable) {
                if (node.parent.childNodes.every(item => {
                    return item.data.status == value
                })) {
                    node.parent.data.status = value
                } else {
                    node.parent.data.status = ''
                }
            } else {
                if (node.parent.childNodes.every(item => {
                    // console.log("aaa:", item.data)
                    return item.data.children && item.data.children.length == 0 || item.data.status == value
                })) {
                    node.parent.data.status = value
                } else {
                    node.parent.data.status = ''
                }
            }

            if (node.parent.parent) {
                this.changeParent(value, node.parent)
            }
        },
        onClickTable(value) {
            if (value) {
                this.tableId = value.id
                this.dialogVisible = true
            }
        },
        saveTreeStatus() {
            let treeData = JSON.parse(JSON.stringify(this.inputValue))
            let tree = { ...this.rootNode, children: this.formatTreeData(treeData) }

            editDataTreeStatus(tree).then(res => {
                this.$message.success('更新成功');
            }).catch(() => {
                this.$message.error('更新失败');
            })
        },
        formatTreeData(treeData) {
            treeData.forEach((item, i) => {
                item.data.status = [item.status ? item.status.toString() : 0]
                treeData[i] = item
                if (item.children.length > 0) {
                    return this.formatTreeData(item.children)
                }
            });
            return treeData;
        },
        onCloseDialog(valid) {
            this.$emit('update', valid)
        }
    }
}
</script>

<style lang="scss" scoped>
.database-dir-tree {
    padding: 10px 0;
    
    &-table {
        border:1px solid #e6e6e6;
        
        .flex {
            flex: 1;
            display: flex;
			align-items: center;
			justify-content: space-between;
        }

		&__header {
			background: #f5f6fa;
			border-bottom: 1px solid #e6e6e6;
            
			&--th {
                padding: 0 10px;
				line-height: 42px;
				color: #1e1e1e;
				font-size: 14px;
                font-weight: 500;
                display: flex;
                align-items: center;

                &:not(:first-child) {
                    width: 100px;
                    border-left: 1px solid #e6e6e6;
                    justify-content: center;
                }

                &:nth-child(2) {
                    width: 150px;
                }

                &:first-child {
                    flex: 1;
                }
			}

			&--switch {
                margin-left: 16px;
            }
		}

        &__main {
            border-bottom: 1px solid rgb(230, 230, 230);
            
            &--td {
                padding: 0 10px;
				height: 40px;
                line-height: 40px;
				font-size: 14px;
                display: flex;
                align-items: center;

                &:not(:first-child) {
                    width: 200px;
                    justify-content: center;
                    border-left: 1px solid #e6e6e6;
                }

                &:nth-child(2) {
                    width: 150px;
                }
                
                &:first-child {
                    flex: 1;
                }

                .item-radio {
                    width: 100px;
                    height: 40px;
                    line-height: 40px;
                    margin: 0;
                    text-align: center;

                    &:last-child {
                        border-left: 1px solid #e6e6e6;
                    }

                    &.placeholder {
                        display: inline-block;
                    }
                }
			}
        }

		::v-deep.el-tree-node__content {
			// margin: 4px 0px;
            padding: 8px 0;
            height: 40px;
            line-height: 40px;
		}
	}

	::v-deep.el-radio {
        .el-radio__inner {
            border-radius: 0;
        }
        .el-radio__input.is-checked {
            .el-radio__inner {
                &::after {
                    content: "";
                    position: absolute;
                    left: 2px;
                    top: 3px;
                    width: 9px;
                    height: 5px;
                    border: 2px solid #fff;
                    border-radius: 1px;
                    border-top: none;
                    border-right: none;
                    background: transparent;
                    transform: rotate(-45deg);
                }
            }
        }	
	}

	.edit-tree {
		padding: 0;

        ::v-deep {
            .el-tree-node:last-child {
                .custom-tree-node {
                    margin-bottom: 2px;
                }
            }
        }
	}

	::v-deep.el-form-item {
		padding-right: 10px;
	}
}
</style>